<template>
  <div class="commonPullDnUp">
    <u-nav-bar v-bind="$attrs">
      <div>
        <slot name="navRight"></slot>
      </div>
    </u-nav-bar>
    <slot name="top"></slot>
    <div class="commonPullDnUp__ct" :class="pullOptions.noData === false ? '' : 'commonPullDnUp__ct__no__rows'">
      <van-pull-refresh v-model="refreshing" @refresh="onPullDownRefresh">
        <van-list
          v-model:loading="loading"
          :finished="pullOptions.finished"
          :finished-text="pageOptions.pageNo > 1 ? pullOptions.finishedText || '我已经到了极限了~' : ''"
          @load="load"
        >
          <slot name="content"></slot>
          <template v-if="pullOptions.noData === true">
            <div class="no-more">
              <slot name="noMore">
                <img src="@/assets/image/no-more.png" />
              </slot>
              <div class="memo">
                <slot name="noMoreText">
                  <span>暂无更多内容</span>
                </slot>
              </div>
            </div>
          </template>
        </van-list>
      </van-pull-refresh>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType, watchEffect, reactive, toRefs } from 'vue'
import { PullRefresh } from 'vant'
import uNavBar from '@/components/NavBar.vue'

export default defineComponent({
  name: 'CommonPullDnUp',
  inheritAttrs: false,
  components: { 'u-nav-bar': uNavBar, 'van-pull-refresh': PullRefresh },
  emits: ['loadData', 'pullDownRefresh', 'update:modelValue'],
  props: {
    pullOptions: {
      type: Object as PropType<{
        rows: any[]
        loading: boolean
        finished: boolean
        refreshing: boolean
        finishedText?: string
        noData: boolean
        [propname: string]: any
      }>,
      required: true
    },
    pageOptions: {
      type: Object as PropType<{
        pageSize: number
        pageNo: number
        [propname: string]: any
      }>,
      required: true
    }
  },
  // 只注重主流程的执行，不同业务的函数拆分出去，业务逻辑清晰明了
  setup(props, { emit, attrs }) {
    const state = reactive<{ refreshing: boolean; loading: boolean }>({
      refreshing: false,
      loading: false
    })

    watchEffect(() => {
      const { refreshing, loading } = props.pullOptions
      state.refreshing = refreshing
      state.loading = loading
    })

    watchEffect(() => {
      emit('update:modelValue', Object.assign(props.pullOptions, state))
    })

    // 事件区域
    const load = async (): Promise<void> => {
      emit('loadData')
    }

    const onPullDownRefresh = () => {
      emit('pullDownRefresh')
      load()
    }

    return {
      ...toRefs(state),
      load,
      onPullDownRefresh
    }
  }
})
</script>

<style lang="scss">
.commonPullDnUp {
  .no-more {
    img {
      width: 200px;
    }
  }
}
</style>

<style lang="scss" scoped>
@import '@/style/variables.scss';
@import '@/style/mixins.scss';
.commonPullDnUp {
  @include flex-cloumn-width-height-100;
  background-color: $background-color-base;
  &__ct {
    @include flex-scroll-content-pd(24px 12px 12px 12px);
    .van-list {
      height: 100%;
    }
    .no-more {
      width: 100%;
      height: 100%;
      opacity: 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      .memo {
        font-size: 12px;
        margin-top: 20px;
        color: $color-text-secondary;
      }
    }
  }
  &__ct__no__rows {
    width: 100%;
    height: 100%;

    .van-list {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
    }
    .no-more {
      width: 100%;
      height: 100%;
      background: white;
      overflow: hidden;
      opacity: 1;
    }
    .van-pull-refresh {
      height: 100%;
    }
  }
}
</style>
